#parse("templates/includes.vtl")

<a name="SpringFramework-IntegratingApacheShirointoSpringbasedApplications"></a>
Integrating Apache Shiro into Spring-based Applications
===

This page covers the ways to integrate Shiro into [Spring](http://spring.io)-based applications.

<a name="SpringFramework-StandaloneApplications"></a>
Standalone Applications
---

Include the Shiro Spring dependency in you application classpath (we recomend using a tool such as Apache Maven or Gradle to manage this).

#dependencies('cli', [['org.apache.shiro', 'shiro-spring', "${earlyRelease}"],['org.springframework', 'spring-context', '${spring.version}']])

Import the Shiro Spring configurations:

``` java
@Configuration
@Import({ShiroBeanConfiguration.class,
         ShiroConfiguration.class,
         ShiroAnnotationProcessorConfiguration.class})
public class CliAppConfig {
   ...
}
```

The above configurations do the following:

| Configuration Class | Description |
| ------------------- | ----------- |
| org.apache.shiro.spring.config.ShiroBeanConfiguration | Configures Shiro's lifecycle and events |
| org.apache.shiro.spring.config.ShiroConfiguration | Configures Shiro Beans (SecurityManager, SessionManager, etc)  |
| org.apache.shiro.spring.config.ShiroAnnotationProcessorConfiguration | Enables Shiro's annotation processing |

The only thing that is left is to configure a [realm](realm.html):

``` java
@Bean
public Realm realm() {
  ...
}
```

The easiest way to setup Shiro, so that all SecurityUtils.* methods work in all cases, is to make the `SecurityManager` bean a static singleton.  DO NOT do this in web applications - see the [Web Applications](#Spring-WebApplications) section below instead.

``` java
@Autowired
private SecurityManager securityManager;
    
 @PostConstruct
 private void initStaticSecurityManager() {
     SecurityUtils.setSecurityManager(securityManager);
 }
```

That is it, now you can get the current `Subject` using:
``` java
SecurityUtils.getSubject();
```

You can see a full example in our [samples on Github](https://github.com/apache/shiro/tree/master/samples/spring).

<a name="SpringFramework-WebApplications"></a>
Web Applications
---

Shiro has first-class support for Spring web applications. In a web application, all Shiro-accessible web requests must go through a master Shiro Filter. This filter itself is extremely powerful, allowing for ad-hoc custom filter chains to be executed based on any URL path expression.

Include the Shiro Spring web dependencies in you application classpath (we recomend using a tool such as Apache Maven or Gradle to manage this).

#dependencies('web', [['org.apache.shiro', 'shiro-spring', "${earlyRelease}"], ['org.apache.shiro', 'shiro-web', "${earlyRelease}"],['org.springframework', 'spring-webmvc', '${spring.version}']])

Import the Shiro Spring configurations:

``` java
@Configuration
@Import({ShiroBeanConfiguration.class,
        ShiroAnnotationProcessorConfiguration.class,
        ShiroWebConfiguration.class,
        ShiroWebFilterConfiguration.class})
public class ApplicationConfig {
  ...
}
```

The above configurations do the following:

| Configuration Class | Description |
| ------------------- | ----------- |
| org.apache.shiro.spring.config.ShiroBeanConfiguration | Configures Shiro's lifecycle and events |
| org.apache.shiro.spring.config.ShiroAnnotationProcessorConfiguration | Enables Shiro's annotation processing |
| org.apache.shiro.spring.web.config.ShiroWebConfiguration | Configures Shiro Beans for web usage (SecurityManager, SessionManager, etc)  |
| org.apache.shiro.spring.web.config.ShiroWebFilterConfiguration | Configures Shiro's web filter |

Provide a Realm implementation:
``` java
@Bean
public Realm realm() {
  ...
}
```

And finally a `ShiroFilterChainDefinition` which will map any application specific paths to a given filter, in order to allow different paths different levels of access. 

``` java
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
    DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
    
    // logged in users with the 'admin' role
    chainDefinition.addPathDefinition("/admin/**", "authc, roles[admin]");
    
    // logged in users with the 'document:read' permission
    chainDefinition.addPathDefinition("/docs/**", "authc, perms[document:read]");
    
    // all other paths require a logged in user
    chainDefinition.addPathDefinition("/**", "authc");
    return chainDefinition;
}
```

If you are using Shiro's annotations see the [annotation](#Spring-annotations-web) section below.

You can see a full example in our [samples on Github](https://github.com/apache/shiro/tree/master/samples/spring-mvc).

<a name="Spring-annotations"></a>
Enabling Shiro Annotations
---

In both standalone and web applications, you might want to use Shiro's Annotations for security checks (for example, `@RequiresRoles`, `@RequiresPermissions`, etc.) These annotations are enabled by importing the `ShiroAnnotationProcessorConfiguration` Spring configuration in both sections above.

Simply annotate your methods in order to use them:

``` java
@RequiresPermissions("document:read")
public void readDocument() {
    ...
}
```

<a name="Spring-annotations-web"></a>
#[[###]]# Annotations and Web Applications

Shiro annotations are fully supported for use in `@Controller` classes, for example:

``` java
@Controller
public class AccountInfoController {

    @RequiresRoles("admin")
    @RequestMapping("/admin/config")
    public String adminConfig(Model model) {
        return "view";
    }
}
```

A `ShiroFilterChainDefinition` bean with at least one definition is still required for this to work, either configure all paths to be accessable via the `anon` filter or a filter in 'permissive' mode, for example: `authcBasic[permissive]`.

``` java
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
    DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
    chainDefinition.addPathDefinition("/**", "anon"); // all paths are managed via annotations
    
    // or allow basic authentication, but NOT require it.
    // chainDefinition.addPathDefinition("/**", "authcBasic[permissive]"); 
    return chainDefinition;
}
```

<a name="Spring-caching"></a>
# Caching 

Enabling caching is as simple as providing a [CacheManager](http://shiro.apache.org/caching.html) bean:

``` java
@Bean
protected CacheManager cacheManager() {
    return new MemoryConstrainedCacheManager();
}
```

<!-- Work around for table styling until, all pages are updated. -->
#mdStyle()

# Configuration Properties

| Key | Default Value | Description |
| --- | ------------- | ----------- |
| shiro.sessionManager.deleteInvalidSessions | `true` | Remove invalid session from session storage |
| shiro.sessionManager.sessionIdCookieEnabled | `true` | Enable session ID to cookie, for session tracking |
| shiro.sessionManager.sessionIdUrlRewritingEnabled | `true` | Enable session URL rewriting support |
| shiro.userNativeSessionManager | `false` | If enabled Shiro will manage the HTTP sessions instead of the container |
| shiro.sessionManager.cookie.name | `JSESSIONID` | Session cookie name |
| shiro.sessionManager.cookie.maxAge | `-1` | Session cookie max age |
| shiro.sessionManager.cookie.domain | null | Session cookie domain |
| shiro.sessionManager.cookie.path | null | Session cookie path |
| shiro.sessionManager.cookie.secure | `false` | Session cookie secure flag |
| shiro.rememberMeManager.cookie.name | `rememberMe` | RememberMe cookie name |
| shiro.rememberMeManager.cookie.maxAge | one year | RememberMe cookie max age |
| shiro.rememberMeManager.cookie.domain | null | RememberMe cookie domain|
| shiro.rememberMeManager.cookie.path | null | RememberMe cookie path|
| shiro.rememberMeManager.cookie.secure | `false` | RememberMe cookie secure flag|
| shiro.loginUrl | `/login.jsp` | Login URL used when unauthenticated users are redirected to login page |
| shiro.successUrl | `/` | Default landing page after a user logs in (if alternative cannot be found in the current session) |
| shiro.unauthorizedUrl | null | Page to redirect user to if they are unauthorized (403 page) |

<input type="hidden" id="ghEditPage" value="spring-framework.md.vtl"></input>
